#ifndef MESH_H
#define MESH_H

#include "OBJLoader.h"
#include "Renderable.h"
#include "Camera.h"
#include "Light.h"
#include <string>
#include <D3D11.h>

using std::string;
using std::vector;


class Mesh : public Renderable
{
public:
	Mesh();
	
	virtual void draw(int subset, ID3DX11Effect* fx, const char* technique) const;
	virtual void draw(const Camera& camera, const vector<Light*>& lights)=0;
	
	void bindVertexIndexBuffers();
	
	void setMaterial(ID3DX11Effect* fx) const;
	virtual ~Mesh();

	virtual void init(const char* filename, ID3D11Device* g_device, ID3D11DeviceContext* g_context);

	void rotateLocalAxis(int axis, float amount);
	void translate(float x, float y, float z);
	void setPos(float x, float y, float z);

	virtual XMMATRIX getWorldMatrix(int subset) const;

	void setNumSubsets(int v) { m_iSubsets = v; }

	void isShadowCaster(bool value) { bShadowCaster = value; }
	bool isShadowCaster() const { return bShadowCaster; }

	void isShadowReceiver(bool value) { bShadowReceiver = value; }
	bool isShadowReceiver() const { return bShadowReceiver; }
	
	void load(const char* filename);

	ID3D11DeviceContext* context() const { return g_context; }
	const XMFLOAT4X4& mtxWorld() const { return m_World; } 

	void setWorldMatrixVal(int i, int j, float v) { m_World(i,j) = v; }
	float getWorldMatrixVal(int i, int j) { return m_World(i,j); }

	ID3D11Device* g_dev() const { return g_device; }

	void setExponent(float v);
	void setCutOffAngle(float v);
	void setDiffuse(float x, float y, float z);
	void setSpecular(float x, float y, float z);
	void createDiffuseTexture(const wchar_t* str);
	
	void setPCSS(bool v) { bUsePCSS = v; }
	bool PCSS() const { return bUsePCSS; }
	
	ID3D11Buffer* getVertexBuffer() { return vertex_buffer; }
	ID3D11Buffer* getIndexBuffer() { return index_buffer; }
	UINT getNumIndices() { return num_indices; }

	bool isLit() const { return bLit; }
	void  isLit(bool v) { bLit = v; }

	void setScale(float v);
	float getScale() const { return scale; }

	int getNumSubsets() const { return m_iSubsets; }

private:
	
	int		m_iSubsets;

	Material _material;

	bool bShadowCaster;
	bool bShadowReceiver;
	bool bUsePCSS;
	bool bLit;

	OBJLoader obj_loader;
	
	ID3D11DeviceContext* g_context;
	ID3D11Device* g_device;
	XMFLOAT4X4			m_World;	

	ID3D11Buffer*		vertex_buffer;
	ID3D11Buffer*		index_buffer;
	ID3D11InputLayout*	input_layout;

	UINT num_vertices;
	UINT num_indices;
	
	float scale;


};



#endif